const express = require('express');
const bcrypt = require('bcrypt');
const formidable = require('formidable');
const Joi = require('joi');
const path = require('path');
const {User} = require('../model/user');
const {Article} = require('../model/article');
const pagenation = require('mongoose-sex-page');
const admin = express.Router();

// 登录访问
admin.get('/login',(req,res)=>{
    res.render('admin/login');
});

// 实现登录的路由
admin.post('/login',async (req,res)=>{
    
    let {email,password} = req.body;
    // 服务器端验证，防止js被禁用
    if(email.trim().length == 0 ||password.trim().length == 0){
        res.status(400).render("admin/login",{msg:'邮箱地址或密码错误'});
        // 阻止代码向下执行
        return;
    }
    let user = await User.findOne({email});
    if(user){
        // 查询到了用户 ：将客户端传递的密码和查询的密码进行比对
        let isEqual = await bcrypt.compare(password,user.password);
        if(isEqual){
            // 登录成功之后将用户名存储在请求对象的session对象中,会自动生成sessionId
            req.session.username = user.username;
            req.session.role = user.role;
            req.app.locals.userInfo = user;
            // 对用户的角色进行判断
            if(user.role == 'admin'){
                res.redirect('/admin/user');
            }else{
                res.redirect('/home/');
            }
        }else{
            res.status(400).render("admin/login",{msg:'邮箱地址或密码错误'}); 
        }
    }else{
        // 未查询到用户
        res.status(400).render("admin/login",{msg:'邮箱地址或密码错误'});
    }
});

// 访问用户页面
admin.get('/user',async (req,res)=>{
    req.app.locals.currentPage = 'user';
    // 接收客户端传递的当前页参数，参数未传递默认为1
    let page = req.query.page || 1;
    // 定义每一页的显示数据数量
    let pagesize = 5;
    // 查询用户的总数
    let count = await User.countDocuments({});
    // 计算总页数
    let total = Math.ceil(count / pagesize);
    let start = (page - 1) * pagesize;
    // 进行查询
    let users = await User.find({}).limit(pagesize).skip(start);
    let right = page-0+1 > total ? 'none' : 'inline';
    res.render('admin/user',{
        users,
        total,
        page
    });
});

// 实现退出登录
admin.get('/logout',(req,res)=>{
    // 删除session
    req.session.destroy(function(){
        // 删除cookie
        res.clearCookie('connect.sid');
        req.app.locals.userInfo = null;
        res.redirect('/admin/login');
    })
});

// 用户编辑页面
admin.get('/user-edit',async (req,res)=>{
    req.app.locals.currentPage = 'user';
    const {msg,id} = req.query;
    console.log(id+"++++++++++++++++++++++++++++++");
    
    if(id){
        let user = await User.findById(id);
        res.render('admin/user-edit',{
            user:user,
            link:'/admin/user-modify?id='+id,
            button:'修改'
        });
    }else{
        res.render('admin/user-edit',{
            msg:msg,
            link:'/admin/user-edit',
            button:'添加'
        });
    }
});

// 用户修改
admin.post('/user-modify', async (req,res,next)=>{
    const body = req.body;
    const id = req.query.id;
    console.log(id);
    
    let user = await User.findById(id);
    console.log(user);
    
    // 密码比对，成功则可以修改，不成功则不能修改
    let flag = await bcrypt.compare(req.body.password,user.password);
    if(flag){
        await User.updateOne({_id:id},{
            username:req.body.username,
            email:req.body.email,
            role:req.body.role,
            state:req.body.state
        });
        res.redirect('/admin/user');
    }else{
        let obj = {path:'/admin/user-edit',msg:'密码比对失败，不能进行信息修改',id:id};
        // next的第一个方法时字符串类型，所以需要将对象转为字符串
        next(JSON.stringify(obj));
    }
});

//用户添加
admin.post('/user-edit',async (req,res)=>{
    // 定义对象的验证规则
    const schema = {
        username:Joi.string().min(2).max(20).required().error(new Error('用户名不符合规则')),
        email:Joi.string().email().error(new Error('邮箱不符合规则')),
        password:Joi.string().required().error(new Error('密码不符合规则')),
        role:Joi.string().valid('normal','admin'),
        state:Joi.number().valid(0,1)
    };
    try{
        // 实施验证
        await Joi.validate(req.body,schema);
    }catch(e){
        // 验证不通过重定向到编辑页面，在编辑页面使用req.msg将错误信息进行显示
        return res.redirect('/admin/user-edit?msg='+e.message);
    }
    let user = await User.findOne({email:req.body.email});
    if(user){
        // 如果用户已经存在，说明邮箱地址已经注册
        return res.redirect('/admin/user-edit?msg=邮箱地址已经被占用');
    }
    // 如果邮箱未占用，则对密码进行加密进行存储
    const salt = await bcrypt.genSalt(10);
    const pass = await bcrypt.hash(req.body.password,salt);
    req.body.password = pass;
    await User.create(req.body);
    res.redirect('/admin/user');
});

// 用户删除
admin.get('/delete',async (req,res)=>{
    let id = req.query.id;
    // res.send(id);
    await User.findOneAndDelete({_id:id});
    res.redirect('/admin/user');
});

// 文章列表页面
admin.get('/article',async (req,res)=>{
    const page = req.query.page;
    req.app.locals.currentPage = 'article';
    // page指定当前页，size指定每页条数 display指定客户端要显示的页码数量 exec向数据库发送查询请求
    let articles = await pagenation(Article).find().page(page).size(5).display(4).populate('author').exec();
    // res.render('admin/article',{
    //     articles:articles
    // });
    res.send
});

// 文章编辑页面
admin.get('/article-edit',async (req,res)=>{
    req.app.locals.currentPage = 'article';
    res.render('admin/article-edit');
});

// 文章添加
admin.post('/article-add',(req,res)=>{
    // 1.创建表单解析对象
    const form = new formidable.IncomingForm();
    // 2.配置上传文件的存放位置
    form.uploadDir = path.join(__dirname,'../','public','uploads'); 
    // 3.保留文件后缀
    form.keepExtensions = true;
    // 4.解析表单
    form.parse(req,async (err,fields,files)=>{
        // fields存储的是普通的表单项，files存储的是二进制文件
        await Article.create({
            title:fields.title,
            author:fields.author,
            publishDate:fields.publishDate,
            cover:files.cover.path.split('public')[1],
            content:fields.content
        });
    });
    res.redirect('/admin/article');
})
module.exports = admin;